package com.common.image_loader;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Enumeration;
import java.util.Hashtable;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.baidu.common.async_http.IResponseListener;
import com.baidu.common.async_http.IResponseProgressListener;
import com.baidu.common.utils.DeviceInfo;
import com.baidu.common.utils.Tools;
import com.common.image_loader.ImageIOReadRequest.Holder;
import com.japher.hackson.AppContext;
import com.japher.hackson.response.BaseResponse;

public class ImageManager
{
	public static boolean load3g = true;

	static class RequestRecord
	{
		RequestImageListener listener;
		String url;
	}

	public static void releaseImage(String imgUrl)
	{
		WeakReference<Bitmap> wr = ramCache.get(imgUrl);
		if (wr != null)
		{
			if (wr.get() != null)
				wr.get().recycle();
		}
		ramCache.remove(imgUrl);
	}

	public static void releaseAllImage()
	{
		Enumeration<String> e = ramCache.keys();
		while (e.hasMoreElements())
		{
			String key = e.nextElement();
			WeakReference<Bitmap> wr = ramCache.get(key);
			if (wr.get() != null)
			{
				if (!wr.get().isRecycled())
					wr.get().recycle();
			}
		}
		ramCache.clear();
	}

	public static void releaseRecycledImage()
	{

		Enumeration<String> e = ramCache.keys();
		while (e.hasMoreElements())
		{
			String key = e.nextElement();
			WeakReference<Bitmap> wr = ramCache.get(key);
			if (wr.get() == null || wr.get().isRecycled())
			{
				ramCache.remove(key);

			}
		}

	}

	private static long lastTime = 0;
	private static Hashtable<String, WeakReference<Bitmap>> ramCache = new Hashtable<String, WeakReference<Bitmap>>();

	/**
	 * 请保证在RequestImageListener的方法在UI线程中执行，因为对于内存中已存在的图片直接回调RequestImageListener
	 * 
	 * @param imageUrl
	 * @param listener
	 */
	public static synchronized void getImage(final String imageUrl, final RequestImageListener listener)
	{
		if (imageUrl == null)
			return;
		/*
		 * if(YouhuiConfig.test) { imageUrl.replace("img3.126.net",
		 * "114.113.198.211"); }
		 */
		if (ramCache.get(imageUrl) != null)
		{
			Bitmap bp = ramCache.get(imageUrl).get();
			if (bp != null && bp.isRecycled())
			{
				ramCache.remove(imageUrl);
				bp = null;
			}
			if (bp != null)
			{
				listener.onRecievedImage(bp);
				return;
			}
		}
		// 旧版本未处理MD5大小写问题，在默认导入图标的情况下要处理读取大小写两种情况

		final String name = Tools.getMD5(imageUrl);
		long size = LocalImageManager.getFileSize(name);
		if (size == -1)
			size = LocalImageManager.getFileSize(name.toUpperCase());
		if (size != -1 && size != 0)
		{
			final Holder params = new Holder();
			params.listener = new RequestImageListener()
			{
				@Override
				public void onRecievedImage(Bitmap bitmap)
				{
					if (params != null && Tools.isEmpty(params.url))
					{
						ramCache.put(params.url, new WeakReference<Bitmap>(params.bitmap));
					}
					
					if(bitmap != null && listener != null)
					{
						listener.onRecievedImage(bitmap);
					}
					else if(bitmap == null)
					{
						//getImage(imageUrl,listener);
					}
				}
				
				@Override
				public void onProgress(int progress)
				{
					if(listener != null)
					{
						listener.onProgress(progress);
					}
				}
			};
			params.url = imageUrl;
			ImageIOReadRequest r = new ImageIOReadRequest(params);
			r.StartRequest();
		}
		else
		{
			if (!load3g)
			{
				long time = System.currentTimeMillis();

				if (time - lastTime > 3000)// 3秒之内不重复判断
				{
					lastTime = time;
					// DeviceInfo.getInstance().resetNetworkState();

				}
				if (!DeviceInfo.getInstance().isWifiConnected(AppContext.getInstance().getContext()))
				{
					if (listener != null)
						listener.onRecievedImage(null);
					return;
				}
			}
			
			if (loading.get(imageUrl) != null)
			{
				if (listener != null)
				{
					if(waitingList != null)
					{
						RequestRecord record = new RequestRecord();
						record.listener = listener;
						record.url = name;
						waitingList.put(name, record);
						return;
					}
				}
			}

			loading.put(imageUrl, "1");
			
			
			ImageRequest r = new ImageRequest(imageUrl);
			r.setProgressListener(new IResponseProgressListener()
			{
				@Override
				public void onProgress(int process)
				{
					if (listener != null)
						listener.onProgress(process);
				}
			});
			r.StartRequest(new IResponseListener()
			{
				@Override
				public void onRequestComplete(BaseResponse response)
				{
					loading.remove(imageUrl);
					if (response instanceof ImageResponse && response.isSuccess())
					{
						ImageResponse r = (ImageResponse) response;
						ByteArrayInputStream in = null;
						if (listener != null)
						{
							Bitmap bt = null;
							try
							{
								in = new ByteArrayInputStream(r.getData());
								bt = BitmapFactory.decodeStream(in);

								ramCache.put(imageUrl, new WeakReference<Bitmap>(bt));
								r.setData(null);

								System.gc();
							}
							catch (Exception e)
							{
								LocalImageManager.delImage(Tools.getMD5(imageUrl));
							}
							catch (OutOfMemoryError error)
							{

							}
							finally
							{
								if (in != null)
								try
								{
									in.close();
								}
								catch (IOException e)
								{
									e.printStackTrace();
								}	
							}

							listener.onRecievedImage(bt);
							if (waitingList != null && waitingList.size() > 0)
							{
								RequestRecord record = waitingList.get(name);
								if (record != null && name.equals(record.url))
								{
									record.listener.onRecievedImage(bt);
								}
								waitingList.remove(name);
							}
						}
					}
					else
					{
						if (listener != null)
							listener.onRecievedImage(null);
					}
				}

			});

		}

	}

	public static void getImageFromSDCard(String imageUrl, RequestImageListener listener)
	{
		String name = Tools.getMD5(imageUrl);
		long size = LocalImageManager.getFileSize(name);
		if (size == -1)
			return;
		
		Holder params = new Holder();
		params.listener = listener;
		params.url = imageUrl;
		ImageIOReadRequest r = new ImageIOReadRequest(params);
		r.StartRequest();
	}

	private static Hashtable<String, String> loading = new Hashtable<String, String>();
	private static Hashtable<String,RequestRecord> waitingList = new Hashtable<String,RequestRecord>();

	public static interface RequestImageListener
	{
		public void onRecievedImage(Bitmap bitmap);

		public void onProgress(int progress);
	}
}
